package com.sh.caryr.erp.controller.trade;

import com.baomidou.mybatisplus.mapper.Wrapper;
import com.sh.caryr.erp.entity.ResultMessage;
import com.sh.caryr.erp.entity.basis.CompCfg;
import com.sh.caryr.erp.entity.definition.CommonFieldDef;
import com.sh.caryr.erp.entity.trade.AsOrder;
import com.sh.caryr.erp.entity.user.User;
import com.sh.caryr.erp.exception.RestServiceException;
import com.sh.caryr.erp.exception.ResultCode;
import com.sh.caryr.erp.service.ICompCfgService;
import com.sh.caryr.erp.service.external.ExtService;
import com.sh.caryr.erp.service.external.ExtServiceFactory;
import com.sh.caryr.erp.service.order.IAsOrderService;
import com.sh.caryr.erp.util.MyBatisUtil;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/api/asOrder")
@SessionAttributes("user")
public class AsOrderController {

    private final IAsOrderService asOrderService;

    private final ICompCfgService compCfgService;

    private final ExtServiceFactory extServiceFactory;

    @Autowired
    public AsOrderController(IAsOrderService asOrderService, ICompCfgService compCfgService, ExtServiceFactory extServiceFactory) {
        this.asOrderService = asOrderService;
        this.compCfgService = compCfgService;
        this.extServiceFactory = extServiceFactory;
    }

    @ApiOperation(value = "Get entity list", notes = "Get entity list")
    @RequestMapping(method = RequestMethod.GET)
    @ResponseStatus(HttpStatus.OK)
    @SuppressWarnings("unchecked")
    public ResultMessage<List<AsOrder>> findAsOrders(
            @RequestParam(defaultValue = "1") Integer current,
            @RequestParam(defaultValue = "20") Integer size,
            @RequestParam(name = "search[value]", required = false) String filters,
            @RequestParam(defaultValue = "id") String orderBy,
            @RequestParam(defaultValue = "false") Boolean isAsc,
            @ModelAttribute("user") User operator) {
        return MyBatisUtil.searchEntities(current, size, filters, orderBy, isAsc, operator, asOrderService);
    }

    @ApiOperation(value = "Update Entity", notes = "Update Entity")
    @ApiImplicitParam(name = "asOrder", value = "asOrder", required = true, dataType = "AsOrder")
    @Transactional
    @RequestMapping(value = "/returnType", method = RequestMethod.PUT)
    @ResponseStatus(HttpStatus.OK)
    public ResultMessage<AsOrder> updateAsOrderReturnType(@RequestBody AsOrder asOrder, @ModelAttribute("user") User operator) {
        MyBatisUtil.updateCommonFields(asOrder, operator);
        try {
            asOrderService.insertOrUpdate(asOrder);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RestServiceException(ResultCode.UNKNOWN);
        }
        return new ResultMessage<>(asOrder);
    }

    @Transactional
    @ApiOperation(value = "Synchronize 3rd party after sales orders")
    @RequestMapping(value = "/syncAsOrder", method = RequestMethod.POST)
    @ResponseStatus(HttpStatus.OK)
    @SuppressWarnings("unchecked")
    public ResultMessage<String> syncAsOrder(@ModelAttribute("user") User operator) {
        List<CompCfg> compConfigs = compCfgService.loadCompCfgByCoco(operator.getCoco());
        int size = 0;
        for (CompCfg compCfg : compConfigs) {
            List<String> extTxnIdList = new ArrayList<>();
            ExtService extSrv = extServiceFactory.getExtService(compCfg);
            List<AsOrder> entities = extSrv.searchAsOrderByDays(compCfg.getSyncAsOrderDays());
            for (AsOrder asOrder : entities) {
                MyBatisUtil.updateCommonFields(asOrder, operator);
                extTxnIdList.add(asOrder.getExtId());
            }
            //--Read old list
            Wrapper<AsOrder> asOrderWrapper = MyBatisUtil.getIsActiveWrapper();
            asOrderWrapper.eq(CommonFieldDef.EXT_PLATFORM, compCfg.getExtPlatform());
            asOrderWrapper.eq(CommonFieldDef.COCO, compCfg.getCoco());
            asOrderWrapper.in(CommonFieldDef.EXT_ID, extTxnIdList);
            List<AsOrder> oldEntities = asOrderService.selectList(asOrderWrapper);
            //--Get update list
            List<AsOrder> updateList = getUpdateList(entities, oldEntities);
            //--Update list
            if (CollectionUtils.isNotEmpty(updateList)) {
                asOrderService.insertOrUpdateBatch(updateList);
                size += updateList.size();
            }
        }
        return new ResultMessage<>("" + size);
    }

    private List<AsOrder> getUpdateList(List<AsOrder> asOrderList, List<AsOrder> oldAsOrderList) {
        List<AsOrder> updateList = new ArrayList<>();
        if (CollectionUtils.isEmpty(oldAsOrderList)) {
            return asOrderList;
        } else if (CollectionUtils.isNotEmpty(asOrderList)) {
            for (AsOrder asOrder : asOrderList) {
                boolean find = false;
                for (AsOrder oldAsOrder : oldAsOrderList) {
                    if (StringUtils.isNotEmpty(asOrder.getExtId()) && asOrder.getExtId().equals(oldAsOrder.getExtId())) {
                        find = true;
                        break;
                    }
                }
                if (!find) {
                    updateList.add(asOrder);
                }
            }
        }
        return updateList;
    }
}
